#include <bits/stdc++.h>
#include <thread>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

using namespace std;

string testFile = "/data/test_data.txt";
string resultFile = "/projects/student/result.txt";

int node_num = 0;
typedef uint account;
typedef vector<int> Loop;
typedef vector<Loop> Loops;
Loops loops3, loops4, loops5, loops6, loops7;
vector<account> nodes;
unordered_map<account, int> idHash;
vector<vector<int>> G;


inline unsigned int parse(char** s){
	char *p = *s;
	unsigned int val = *(p++) - '0';
	while(*p != ','){
		val = 10*val + *(p++) - '0';
	}
	*s = p+1;
	return val;
}
void loadData_and_createGrap(){
	int fd = open(testFile.c_str(), O_RDONLY);
    int file_size = lseek(fd, 0, SEEK_END);
    char* p_map =(char*)mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
	char *p = p_map;
	vector<account> inputs;
	while(*p != '\0'){
		inputs.push_back(parse(&p));
		inputs.push_back(parse(&p));
		while(*p != '\n') p++;
		p++;
	}
	nodes = inputs;
	sort(nodes.begin(),nodes.end());//排序
	nodes.erase(unique(nodes.begin(),nodes.end()),nodes.end());//去重
	for(uint& v:nodes) idHash[v] = node_num++;
	G = vector<vector<int>>(node_num);
	for(int i=0; i<inputs.size(); i+=2) G[idHash[inputs[i]]].push_back(idHash[inputs[i+1]]);
	for(int i=0; i<node_num; i++) sort(G[i].begin(),G[i].end());
	munmap(p_map, file_size);
}

char buf[77*3*1000000];
char* p = buf;

void uint_to_char(const Loop& loop){
	string tmp = to_string(nodes[loop[0]]);
	int size = tmp.size();
	memcpy(p, tmp.c_str(), size);
	p += size;
	for(int i=1; i<loop.size(); i++){
		tmp = to_string(nodes[loop[i]]);
		size = tmp.size();
		*(p++) = ',';
		memcpy(p, tmp.c_str(), size);
		p += size;
	}
	*(p++) = '\n';
}

void save(){
	int num = loops3.size()+loops4.size()+loops5.size()+loops6.size()+loops7.size();
	string tmp = to_string(num);
	int size = tmp.size();
	memcpy(p, tmp.c_str(), size);
	p += size;
	*(p++) = '\n';
	for(auto& loop:loops3) uint_to_char(loop);
	for(auto& loop:loops4) uint_to_char(loop);
	for(auto& loop:loops5) uint_to_char(loop);
	for(auto& loop:loops6) uint_to_char(loop);
	for(auto& loop:loops7) uint_to_char(loop);
	int data_size = p - buf;
	int fd = open(resultFile.c_str(), O_RDWR|O_CREAT, 0666);
	ftruncate(fd, data_size);
	char* p_map =(char*)mmap(NULL, data_size, PROT_WRITE, MAP_SHARED, fd, 0);
	memcpy(p_map, buf, data_size);
	munmap(p_map, data_size);
	close(fd);
}

int main(int argc, char* argv[]){
	loadData_and_createGrap();
	vector<int> uSet2, uSet3, uSet4, uSet5;
	Loop lp;
	for(int u=0; u<node_num; u++){
		for(int& v1:G[u]){
			if(v1 < u) continue;
			for(int& v2:G[v1]) if(v2 > u) uSet2.push_back(v2);
			for(int& v2:uSet2){
				if(find(G[v2].begin(),G[v2].end(),u)!=G[v2].end()){
					lp.push_back(u);
					lp.push_back(v1);
					lp.push_back(v2);
					loops3.push_back(lp);
					lp.clear();
				}
				for(int& v3:G[v2]) if(v3 > u && v3!=v1) uSet3.push_back(v3);
				for(int& v3:uSet3){
					if(find(G[v3].begin(),G[v3].end(),u)!=G[v3].end()){
						lp.push_back(u);
						lp.push_back(v1);
						lp.push_back(v2);
						lp.push_back(v3);
						loops4.push_back(lp);
						lp.clear();
					}
					for(int& v4:G[v3]) if(v4 > u && v4!=v2 && v4!=v1) uSet4.push_back(v4);
					for(int& v4:uSet4){
						if(find(G[v4].begin(),G[v4].end(),u)!=G[v4].end()){
							lp.push_back(u);
							lp.push_back(v1);
							lp.push_back(v2);
							lp.push_back(v3);
							lp.push_back(v4);
							loops5.push_back(lp);
							lp.clear();
						}
						for(int& v5:G[v4]) if(v5 > u && v5!=v3 && v5!=v2 && v5!=v1) uSet5.push_back(v5);
						for(int& v5:uSet5){
							if(find(G[v5].begin(),G[v5].end(),u)!=G[v5].end()){
								lp.push_back(u);
								lp.push_back(v1);
								lp.push_back(v2);
								lp.push_back(v3);
								lp.push_back(v4);
								lp.push_back(v5);
								loops6.push_back(lp);
								lp.clear();
							}
							for(int& v6:G[v5]){
								if(v6 > u && v6!=v4 && v6!=v3 && v6!=v2 && v6!=v1){
									if(find(G[v6].begin(),G[v6].end(),u)!=G[v6].end()){
										lp.push_back(u);
										lp.push_back(v1);
										lp.push_back(v2);
										lp.push_back(v3);
										lp.push_back(v4);
										lp.push_back(v5);
										lp.push_back(v6);
										loops7.push_back(lp);
										lp.clear();
										continue;
									}
								}
							}
							
						}
						uSet5.clear();
					}
					uSet4.clear();
				}
				uSet3.clear();
			}
			uSet2.clear();
		}
	}
	
	save();
	exit(0);
}